/*
 * MIT License
 *
 * Copyright (c) 2020 wen.gu <454727014@qq.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/***************************************************************************
 * Name: cbus_endpoint_ops.h
 *
 * Purpose: define the endpoint ops API
 *
 * Developer:
 *   wen.gu , 2022-03-12
 *
 * TODO:
 *
 ***************************************************************************/

/******************************************************************************
 **    INCLUDES
 ******************************************************************************/
#ifndef __CBUS_ENDPOINT_OPS_H__
#define __CBUS_ENDPOINT_OPS_H__

#include <stdio.h>

#include "cbus/core/cbus_type.h"

#include "cbus/bus/cbus_message.h"
/******************************************************************************
 **    MACROS
 ******************************************************************************/
/**
 *  we define the version as hex number, the high order byte aways as hex
 * 43 45 : 'C' 'E' (mean cbus endpoint).  just increase low order byte.
 * e.g the next version CBUS_EP_V1 maybe 0x43420001
*/
#define CBUS_EP_V0 0x43450000

#define CBUS_EP_VERSION CBUS_EP_V0
/******************************************************************************
 **    TYPE DEFINITIONS
 ******************************************************************************/
G_C_HEADER_START

typedef enum _cbus_endpoint_role
{/** EP: endpoint */
    CBUS_EP_RE_NONE = 0,
    CBUS_EP_ROLE_SERVICE, /** implementation endpoint as service */
    CBUS_EP_ROLE_CLIENT, /** implementation endpoint as client */
}cbus_endpoint_role;

/** @brief a callback function to listen the connect status between current Endpoint and 
 * source(current endpoint as service)/target(current endpoint as client) Endpoint
 * @param opaque       [in] a handle which user set to Endpoint
 * @param endpoint_id  [in] the ID of source(current endpoint as service)/
 *                         target(current endpoint as client) Endpoint
 * @param is_connected [in]  GTRUE: the source/target endpoint and current endpoint has 
 *                                  build a connection
 *                           GFALSE: the connection has disconnected
 * */
typedef void (*cbus_endpoint_on_connect_changed_func)(GPTR opaque, cbus_endpoint_id endpoint_id, GBOL is_connected);

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////


typedef void (*cbus_endpoint_on_receive_func)(GPTR opaque, cbus_endpoint_id endpoint_id, const GBUF data, GU32 size);

///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
typedef struct _cbus_endpoint_ops
{
    cbus_endpoint_role role;
    GVER version;
    const GSTR name;

    GErrc (*initialize)(GPHD* handle, const GSTR url);
    void (*finish)(GPHD handle);
    
    GErrc (*start)(GPHD handle);
    GErrc (*stop)(GPHD handle);

    GErrc (*set_on_connect)(GPHD handle, cbus_endpoint_on_connect_changed_func on_connect, GPTR opaque);
    GErrc (*set_on_receive)(GPHD handle, cbus_endpoint_id endpoint_id, cbus_endpoint_on_receive_func on_receive, GPTR opaque);

    GErrc (*send)(GPHD handle, cbus_endpoint_id endpoint_id, const GBUF data, GU32 size); 

}cbus_endpoint_ops;

/******************************************************************************
 **    CLASSES/FUNCTIONS DEFINITIONS
 ******************************************************************************/
/**
 * @brief initislize the default endpoints
 * 
 * @return success: G_OK, else: error code @see GErrc
 */
G_API GErrc cbus_endpoint_ops_initialize(void);

/**
 * @brief uninitialize endpoint
 * @param void none
 * @return void
 */
G_API void cbus_endpoint_ops_finish(void);

/**
 * @brief find a valid endpoint class with name
 * 
 * @param role [in] the role of endpoint
 * @return cbus_endpoint_ops* the reference of a endpoint class
 */
G_API const cbus_endpoint_ops* cbus_endpoint_ops_find(cbus_endpoint_role role, const GSTR name);

/**
 * @brief register a endpoint class dynamicly
 * 
 * @param cbus_endpoint [in] a reference of a endpoint class
 * @return success: G_OK, else error coce @see GErrc
 */
G_API GErrc cbus_endpoint_ops_register(const cbus_endpoint_ops* ep_ops);

G_C_HEADER_END

#endif /** !__CBUS_ENDPOINT_OPS_H__ */

